#! /bin/bash
# update by shang.kun
# Used to do BMC reset
version=`cat README.md|grep -i Current_version`
cycle=0
fault_fun=0
outband=0
random=0
tmp=./reports/tmp
first=./reports/first_cycle_log

function logs () 
{
if [ "`ls reports`" != ""  ]; then
    read -p "Please check if romove logs file: (y/n default:y)" r
    if [ -z $r ];then
        r=y
    fi
    case $r in
        Y|y)
            rm -rf ./reports/*
            ;;
        N|n)
            mkdir -p ./reports/before
            mv -f ./reports/* ./reports/before
    esac
fi
}

function IPMI_FF () 
{
if [ $outband -eq 1 ]; then
    export IPMI="ipmitool -H $BMCip -U $User -P $passwd"
    ipmi_ali="ipmitool.dat -H $BMCip -U $User -P $passwd"
else
    export IPMI=ipmitool
    ipmi_ali="ipmitool.dat"
fi
}


function base_info () #check 基础信息包含 device_id、mac adrress、 fru
{
    echo "********Cycle$i********" >> ./reports/base_info_full.log
    echo "####device id####" > ./reports/base_info.log
    $IPMI raw 6 1 >> ./reports/base_info.log
    echo "####Dedicate LAN MAC Address####" >> ./reports/base_info.log
    $IPMI lan print 1 | grep -i "MAC Address" >> ./reports/base_info.log
    echo "####Fru info####" >> ./reports/base_info.log
    $IPMI fru print 0 >> ./reports/base_info.log
    if [ $i -eq 1 ];then
        echo -e "\033[32m The First cycle base info(device id, lan, fru): \033[0m"
        cat ./reports/base_info.log | tee -a $first/base_info_first.log
        cat ./reports/base_info.log >> ./reports/base_info_full.log
    else
        cat ./reports/base_info.log >> ./reports/base_info_full.log
        if [  "`diff  $first/base_info_first.log ./reports/base_info.log`" == "" ];then
            printf "%-45s%s\n" "NO.1 Check base info(device id,mac,fru)" "PASS" >> ./reports/Summary.log
        else
            printf "%-45s%s\n" "NO.1 Check base info(device id,mac,fru)" "FAIL" >> ./reports/Summary.log
            diff  $first/base_info_first.log ./reports/base_info.log >> ./reports/base_info_full.log
        fi
    fi 
}

function SDR () 
{
    echo "********Cycle$i********" >> ./reports/sdr_full.log
    $IPMI sdr elist > ./reports/sdr.log
    if [ $i -eq 1 ];then
        echo -e "\033[32m The First cycle sdr info: \033[0m"
        cat ./reports/sdr.log | tee -a $first/sdr_first.log
        echo " "
        cat ./reports/sdr.log | awk '{print $1$2$3$4$5$6$7}' > $tmp/sdr_first_tmp.log
        cat ./reports/sdr.log >> ./reports/sdr_full.log
    else
        cat ./reports/sdr.log >> ./reports/sdr_full.log
        cat ./reports/sdr.log | awk '{print $1$2$3$4$5$6$7}' > $tmp/sdr_tmp.log
        if [  "`diff $tmp/sdr_first_tmp.log $tmp/sdr_tmp.log`" == "" ];then
            printf "%-45s%s\n" "NO.2 Check sdr info" "PASS" >> ./reports/Summary.log
        else
            printf "%-45s%s\n" "NO.2 Check sdr info " "FAIL" >> ./reports/Summary.log
            diff $tmp/sdr_first_tmp.log $tmp/sdr_tmp.log >> ./reports/sdr_full.log
        fi
    fi   
}


function SEL ()      #当为第一个cycle的时候，SEL这个function,会提示check第一圈收集到的BMC基础信息、SEL log是否正确
{                       
    echo "********Cycle$i********" >> ./reports/sel_full.log
    $IPMI sel elist > ./reports/sel.log
    $IPMI sel save ./reports/sel_raw_log/Cycle${i}_raw.log
    if [ $i -eq 1 ];then
        echo -e "\033[32m The First cycle sel log: \033[0m"
        cat ./reports/sel.log | tee -a $firts/sel_first.log
        echo " "
        cat ./reports/sel.log >> ./reports/sel_full.log
        read -p "Please check first cycle basic logs if correct: (y/n default:y)" r1
        if [ -z $r1 ];then
            r1=y
        fi
        case $r1 in
            Y|y)
                printf "%-45s%s\n" "NO.1 Check base info(device id,mac,fru)" "PASS" >> ./reports/Summary.log
                printf "%-45s%s\n" "NO.2 Check sdr info" "PASS" >> ./reports/Summary.log
                printf "%-45s%s\n" "NO.3 Check sel log" "PASS" >> ./reports/Summary.log
                ;;
            N|n)
                exit 1
        esac
        cat ./reports/sel.log | awk -F "|" '{print $4"|"$5"|"$6}' | sort  > $tmp/sel_first_tmp.log
        sleep 0.2
        $IPMI sel clear > /dev/null
    else
        cat ./reports/sel.log >> ./reports/sel_full.log
        cat ./reports/sel.log | awk -F "|" '{print $4"|"$5"|"$6}' | sort > $tmp/sel_tmp.log
        if [  "`diff $tmp/sel_first_tmp.log $tmp/sel_tmp.log`" == "" ];then
            printf "%-45s%s\n" "NO.3 Check sel log" "PASS" >> ./reports/Summary.log
        else
            printf "%-45s%s\n" "NO.3 Check sel log" "FAIL" >> ./reports/Summary.log
            diff $tmp/sel_first_tmp.log $tmp/sel_tmp.log >> ./reports/sel_full.log
        fi
        sleep 0.2
        $IPMI sel clear > /dev/null
    fi   
}

function fault () 
{
    echo "********Cycle$i********" >> ./reports/fault_full.log
    ./$ipmi_ali alioem sel > ./reports/fault.log
    if [ $i -eq 1 ];then
        echo -e "\033[32m The First cycle fault log: \033[0m"
        cat ./reports/fault.log  | tee -a  ./$first/fault_first.log
        echo " "
        read -p "Please check first cycle fault log if correct: (y/n default:y)" r2
        if [ -z $r2 ]; then
            r2=y
        fi
        case $r2 in
            Y|y)
                printf "%-45s%s\n" "NO.4 Check fault log" "PASS" >> ./reports/Summary.log
                ;;
            N|n)
                exit 1
        esac
        cat ./reports/fault.log | awk -F "|" '{print $3$4$5$6}' | sort > $tmp/fault_first_tmp.log
        cat ./reports/fault.log >> ./reports/fault_full.log
        sleep 0.2
        $IPMI  raw 0x30 0xe0 0 0x4c 0xa5 0xe0 0xff 0xff
    else
        cat ./reports/fault.log >> ./reports/fault_full.log
        cat ./reports/fault.log | awk -F "|" '{print $3$4$5$6}' | sort > $tmp/fault_tmp.log
        if [ "`diff $tmp/fault_first_tmp.log $tmp/fault_tmp.log`" == "" ];then
            printf "%-45s%s\n" "NO.4 Check fault log" "PASS" >> ./reports/Summary.log
        else
            printf "%-45s%s\n" "NO.4 Check fault log" "FAIL" >> ./reports/Summary.log
            diff $tmp/fault_first_tmp.log $tmp/fault_tmp.log >> ./reports/fault_full.log
        fi
        sleep 0.2
        $IPMI  raw 0x30 0xe0 0 0x4c 0xa5 0xe0 0xff 0xff
    fi   
}

function init () 
{
    . /etc/init.d/functions
	$IPMI sel clear
	[ $? -eq 0 ]&& action "clear sel log" true||action "clear sel log" false
	sleep 1
	$IPMI  raw 0x30 0xe0 0 0x4c 0xa5 0xe0 0xff 0xff
	[ $? -eq 0 ]&& action "clear fault log" true||action "clear fault log" false
	dmesg -C||dmesg -c
	[ $? -eq 0 ]&& action "clear dmesg log" true||action "clear dmesg log" false
}

function random_reset ()
{
    random_time=$(($RANDOM%180))
    $IPMI raw 6 2
    if [ $i -ne 1 ]; then
        sleep 30  #sleep这个时间的原因是下了BMC重启的命令的一段时间内，ipmi命令还能用，通过sleep30S确认BMC确实在重启
        printf "%-45s%d%s\n" "BMC random reset Randmon deley time" "$random_time" "S" >> ./reports/Summary.log
    else
        if [ $blackbox_function -eq 1 ]; then
            nohup ./Blackbox_check.sh &
        else    
            sleep 0.1
        fi
        sleep 1
        printf "%-45s\n" "BMC reset first cycle not random reset" >> ./reports/Summary.log
        read -p "First cycle not random reset, please insert first cycle full time (default 100(s)):" r3
        if [ -z $r3 ]; then
            sleep 100
        else
            sleep $r3
        fi
        return 1
    fi
    while true
    do
        $IPMI raw 6 1 > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            sleep 0.1
            break
        fi
    done
    if [ $blackbox_function -eq 1 ]; then
        nohup ./Blackbox_check.sh &
    else 
        sleep 0.1
    fi
    sleep $random_time  
}

function blackbox ()
{    
    $IPMI raw 0x30 0xc0 > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        blackbox_function=1
        echo "**Blackbox Function will be disabled**"
    else
        blackbox_function=0
        echo "**Cannot support Blackbox_Function**"
    fi
}
	
function BMC_reset_help () 
{
more << EOF
    -h|--help    help info
    -v           list version
    -c           Run BMC reset cycle
    -t           BMC reset time every cycle
    -H           BMC IP
    -U           BMC User name
    -P           BMC Password
    -y           answer all questions
    --init       Clear log before test
    --random     BMC reset random test: BMC is not fully up, but ipmi can be used then random dely 0-180S, restart BMC again 
    --fault      Collect fault logs
    example
    *************************************************
    inband:
      $0 --init
      $0 -c 1000 -t 100
      $0 -c 1000 --random
    outband:
      $0 -H xx -U xx -P xx --init
      $0 -H xx  -U xx -P xx -c 1000 -t 100 
      $0 -H xx  -U xx -P xx -c 1000 --random
    *************************************************	
EOF
}

#main

if [ $# -eq 0 ];then
    echo "Please run $0 -h|--help to check help info"
    exit 1	   
fi

while [ "$1" != "" ]
do
    case $1 in
        -h|--help)
            BMC_reset_help ;;
        -v)
            echo $version ;;
        -H)
            shift ; BMCip=$1 ; outband=1 ;;
        -U)
            shift ; User=$1 ;;
        -P)
            shift ; passwd=$1 ;;	  
        -c)
            shift ; cycle=$1 ;;
        -t)
            shift ; time=$1 ;;
        -y)
            r=y ; r1=y; r2=y; r3=100;;
        --init)
           IPMI_FF ; init ;;
        --fault)
            fault_fun=1 ;;
        --random)
            random=1;;
        *)
            echo "Please run $0 -h|--help to check help info"
            exit 1	   	
    esac
    shift
done

if [  $cycle -eq 0 ];then
    exit 3
else
    logs
    mkdir -p $tmp
    mkdir -p $first
    mkdir -p ./reports/sel_raw_log
    IPMI_FF
    blackbox
    for ((i=1;i<=$cycle;i++))
    do
        echo -e "\033[32m Now is cycle $i/$cycle \033[0m" 
        echo "********Cycle$i********" >> ./reports/Summary.log
        if [ $random -eq 0 ]; then
            $IPMI raw 6 2
            if [ $blackbox_function -eq 1 ]; then
                nohup ./Blackbox_check.sh &
            else sleep 0.1
            fi
            sleep $time
        else
            random_reset
        fi
        base_info
        SDR 
        SEL
        if [ $fault_fun -eq 1 ];then 
        fault
        fi
    done
fi

if [ "`cat ./reports/Summary.log | grep -i fail`"  == "" ]; then
more << EOF |tee -a ./reports/Summary.log
BMC_reset_test_result:
    ********     *        ******   ******
    *      *    * *       *        * 
    *      *   *   *      *        * 
    ********  * *** *     ******   ****** 
    *        *       *         *        *
    *       *         *        *        *
    *      *           *  ******  *******
EOF
else
more << EOF | tee -a ./reports/Summary.log
BMC_reset_test_result:
    ********   *        *  *
    *         * *       *  *
    *        *   *      *  *
    *****   * *** *     *  *
    *      *       *    *  *
    *     *         *   *  *
    *    *           *  *  *******
EOF
fi
